-- 战斗UI-左/右上方entity头像节点

local PlayerNode = class("PlayerNode",function(node) return node end)
local SkillView = require("app.battleV3.ui.objs.MeleeSkillOnHead")

local NodePool = custom.NodePool:getInstance()

PlayerNode.Event_ShowPlayerTips = "Event_ShowPlayerTips"
PlayerNode.Event_HidePlayerTips = "Event_HidePlayerTips"


PlayerNode.Event_SetCurrentTarget = "Event_PlayerNodeSetCurrentTarget"


local EBattleActorType_Self = Enums.BattleActorType.self
local EBattleActorType_Teammate = Enums.BattleActorType.teammate
local EBattleActorType_Enemy = Enums.BattleActorType.enemy
local EBattleActorType_Boss = Enums.BattleActorType.boss
local TAG_CD = 101
local SELF_SORT_WEIGHT = 99999

local specialHPPanelWidth = 48 -- 特殊血条 panel宽

function PlayerNode.create(isLeft, id, bEnemy, isTimeMonster, npcKind)
	local ret = NodePool:getByKey("PlayerNode")
	--[[
	if ret then
		print("====>PlayerNode.create from pool ",NodePool:size("PlayerNode"))
	end
	]]

	if not ret then
		local resPath = Res.BattlePlayerHead

		local playerUI = cc.CSLoader:createNode(resPath,false,true)
		local oldPlayerNode = playerUI:getChildByName("Panel")
		local playerNode = display.replaceNodeToMultipleLayerNode(oldPlayerNode)
		oldPlayerNode:removeFromParent()

	    -- local default_item = ccui.Layout:create()
	    -- default_item:setTouchEnabled(false)
	    -- local width,height = playerNode:getContentSize2()

	    -- default_item:setContentSize(cc.size(width*playerNode:getScaleX(),height*playerNode:getScaleY()))
	    -- default_item:addChild(playerNode)
	    -- playerNode:setPosition(width/2,height/2)
	    ret = PlayerNode.new(playerNode, playerNode)
	end

	ret:reset()
	ret:setIsLeft(isLeft)
	ret:setId(id)
	ret:setEnemy(bEnemy, npcKind)
	ret:setIsTimeMonster(isTimeMonster)
	ret:setFlip()
    return ret
end

function PlayerNode:ctor(node,rootNode)
	cc(self):addComponent("components.behavior.SimpleEvent"):exportMethods()
	self.mRootNode = rootNode

	self.initScale = rootNode:getScale()
	self.initOpacity = rootNode:getOpacity()

	self.mTeamBtn = rootNode:findChild("Panel_bg/bg_team")
	self.mEnemyBtn = rootNode:findChild("Panel_bg/bg_foe")

	self.mTeamBtnElite = rootNode:findChild("Panel_bg/bg_elite_team")
	self.mEnemyBtnElite = rootNode:findChild("Panel_bg/bg_elite_foe")
	self.mTeamBtnBoss = rootNode:findChild("Panel_bg/bg_boss_team")
	self.mEnemyBtnBoss = rootNode:findChild("Panel_bg/bg_boss_foe")

	-- 头像图标
	local iconGroup = rootNode:findChild("Panel_head")
	self.iconGroup = iconGroup

	self.mIcon = iconGroup:findChild("icon_img")
    self.mIcon:setVisible(false)
	--dead mask
	self.signDead = rootNode:findChild("Panel_sign/img_death")
	self.signEye = rootNode:findChild("Panel_sign/img_eye")
	self.signTeam = rootNode:findChild("Panel_sign/img_team")
	self._barRoot = rootNode:findChild("Panel_hp")
	self._hpVisibleFlag = true
	self.hpBarTeam = self._barRoot:findChild("bar_team")
	self.hpBarEnemy = self._barRoot:findChild("bar_foe")
	self.specialHPSign = self._barRoot:findChild("Panel")
	specialHPPanelWidth = self.specialHPSign:getContentSize2()

	--时间怪
	self.timeMonsterIcon = rootNode:findChild("icon_time")
	--cd
    self.mCdNode = rootNode:findChild("Panel_cd")
    self.mCdMask = self.mCdNode:findChild("img_cd")
    self.mCdMask:setVisible(false)
    self.cdSprite = self.mCdNode:getChildByTag(TAG_CD)
    if not self.cdSprite then
        self.cdSprite = cc.ProgressTimer:create( self.mCdMask )
        self.cdSprite:setType( cc.PROGRESS_TIMER_TYPE_RADIAL )
        self.cdSprite:setMidpoint(cc.p( 0.5, 0.5 ))
        self.cdSprite:setPosition(self.mCdMask:getPosition())
        self.cdSprite:setTag(TAG_CD)
        self.cdSprite:setScaleX(-0.8)
        self.cdSprite:setScaleY(0.8)
        self.mCdNode:addChild(self.cdSprite, -1)
    end

    self.mCdNum = self.mCdNode:findChild("time")
    self.skillBar = rootNode:findChild("skillBar")
    self.aniBreak = rootNode:findChild("ani_break")
    self.breakAction = cc.CSLoader:createTimeline(Res.AniBreakEffect)
    if self.breakAction then
        self.aniBreak:runAction(self.breakAction)
        self.breakAction:gotoFrameAndPlay(0, self.breakAction:getDuration(), true)
    end

   	self.skillView = SkillView.new(rootNode:findChild("head_s"))
end

function PlayerNode:setSkillBar(percent)
	if not self.bEnemy then
		return
	end

	if self.skillBar and percent>0 and percent<100 then
		self.skillBar:setVisible(true)
		self.skillBar:setPercent(percent)
	else
		self.skillBar:setVisible(false)
	end
end

function PlayerNode:playCanBreak(bShow)
	if self.bSelf then
		return
	end
	if not EFFECT_ALL_SHOW then
		return
	end
	if self.lastShowState ~= bShow then
		if bShow then
			self.aniBreak:setVisible(true)
			if not self.lianxieEffect then
				self.lianxieEffect = display.newArmature({path=Res.Lianxie.dir,armatureName=Res.Lianxie.name,animationName="",skeletonName=Res.Lianxie.name})
				self.aniBreak:addChild(self.lianxieEffect)
				self.lianxieEffect:getAnimation():gotoAndPlay("lianxie1")
				self.lianxieEffect:setScale(0.8)
			end
		else
			self.aniBreak:setVisible(false)
			if self.lianxieEffect then
				self.lianxieEffect:removeFromParent()
				self.lianxieEffect = nil
			end
		end
	end
	self.lastShowState = bShow
end

function PlayerNode:setCD(time,needTime)
	if time<=0 then
		self.mCdNode:setVisible(false)
	else
		self.mCdNode:setVisible(true)
	    self.mCdNum:setString(string.format("%.1f", time/1000))
	    local percent = time/needTime
	    self.cdSprite:setPercentage(100*percent)
	end
end

function PlayerNode:hideCD()
	self.mCdNode:setVisible(false)
end

function PlayerNode:reset()
	self:removeAllEventListeners()

	self.isCurrentPlayerTarget = false
	self.mHpPrecent = 100
	self.isSelf = false
	self.actorType = EBattleActorType_Enemy

	self.signDead:setVisible(false)
	self.signTeam:setVisible(false)
	self.signEye:setVisible(false)

	if not cc.isDead(self.hpHideEffectNode) then
		self.hpHideEffectNode:removeFromParent()
		self.hpHideEffectNode = nil
	end

	self.mIcon:stopAllActions()
	self.mIcon:setOpacity(255)

	self.mRootNode:stopAllActions()
	self.mRootNode:setOpacity(self.initOpacity)
	self.mRootNode:setScale(self.initScale)

	--self:unscheduleUpdate()
	--self:scheduleUpdate( handler(self, PlayerNode.updateFrame))
	self:clearEvent()
	BattleUIEvent:addObjToFrameUpdate(self,PlayerNode.updateFrame)

end

function PlayerNode:clearEvent()
	BattleUIEvent:removeFromUpdate(self)
end

function PlayerNode:setIsLeft(b)
	self.isLeft = b
end

function PlayerNode:setId(id)
	self._id = id
end

function PlayerNode:setEnemy(b, npcKind)
	self.mTeamBtn:setVisible(false)
	self.mEnemyBtn:setVisible(false)
	self.mTeamBtnElite:setVisible(false)
	self.mEnemyBtnElite:setVisible(false)
	self.mTeamBtnBoss:setVisible(false)
	self.mEnemyBtnBoss:setVisible(false)

	self.bEnemy = b

	self.skillView:setLeft(not b)

	if b then
		if npcKind == Enums.NpcKind.NpcKind_Elite then
			self.mTipsBtn = self.mEnemyBtnElite
		elseif npcKind == Enums.NpcKind.NpcKind_Boss then
			self.mTipsBtn = self.mEnemyBtnBoss
		else
			self.mTipsBtn = self.mEnemyBtn
		end
	else
		if npcKind == Enums.NpcKind.NpcKind_Elite then
			self.mTipsBtn = self.mTeamBtnElite
		elseif npcKind == Enums.NpcKind.NpcKind_Boss then
			self.mTipsBtn = self.mTeamBtnBoss
		else
			self.mTipsBtn = self.mTeamBtn
		end
	end

	self.mTipsBtn:setVisible(true)

	if b then
		self.hpBarTeam:setVisible(false)
		self.hpBar =  self.hpBarEnemy
	else
		self.hpBarEnemy:setVisible(false)
		self.hpBar = self.hpBarTeam
	end

	self.hpBar:setVisible(true)

	self:addButtonListener()
end

function PlayerNode:setIsTimeMonster(b)
    self.timeMonsterIcon:setVisible(b)
end

function PlayerNode:CreateClippingNode(stencilNode,contentNode)
    if tolua.isnull(stencilNode) or tolua.isnull(contentNode) then
        print("getOrCreateHeroIconClipping fail")
    else
        print("getOrCreateHeroIconClipping ok")
        contentNode:retain()
        if contentNode:getParent() then
        	contentNode:removeFromParent()
        end
        stencilNode:retain()
        if stencilNode:getParent() then
        	stencilNode:removeFromParent()
        end
        local clipNode = cc.ClippingNode:create()
        clipNode:setInverted(false)
        clipNode:setAlphaThreshold(0.5)
        if stencilNode then
            clipNode:setStencil(stencilNode)
            stencilNode:setVisible(true)
            contentNode:setContentSize(stencilNode:getContentSize())
            contentNode:setPosition(stencilNode:getPosition())
        end
        clipNode:addChild(contentNode)
        contentNode:release()
        stencilNode:release()
      	return clipNode
    end
end

function PlayerNode:addButtonListener()
	local function touchEvent_ShowTips(sender, eventType)
        if eventType == ccui.TouchEventType.began then
        	BattleUIEvent:dispatchEvent(BattleUIEvent.TYPE.BATTLE_CANCEL_AUTO)
        elseif eventType == ccui.TouchEventType.ended then
			local isCurrentPlayerTarget = self.isCurrentPlayerTarget
			AM.play(Res.BattleTargetClick, false)
			if not isCurrentPlayerTarget then
				self:dispatchEvent(PlayerNode.Event_SetCurrentTarget, self._id, true)
			end
        end
    end
    self.mTipsBtn:addTouchEventListener(touchEvent_ShowTips)
end

function PlayerNode:setIcon(iconFile)
	if self.mIcon and iconFile then
        self.mIcon:setVisible(true)
		self.mIcon:loadTexture(iconFile)
	end
end

function PlayerNode:getIcon()
	return self.mIcon
end

function PlayerNode:getHpBar()
	return self.hpBar
end

function PlayerNode:setSpecialHPMax( specialHPMax )
	if self._specialHPInitEnd then
		return
	end
	local isSpecialHPFlag = 0 < specialHPMax or false
	self.specialHPSign:setVisible( isSpecialHPFlag )
	if isSpecialHPFlag then
		local shownNum = 0
		local nodeListTemp = {}
		for i = 1, Constant.BattleSpecialHPNodeMaxNum do
			local ndoeTemp = self.specialHPSign:getChildByName( "Image_" .. i )
			table.insert( nodeListTemp, ndoeTemp )

			if i < specialHPMax then
				shownNum = shownNum + 1
				ndoeTemp:setVisible( true )
			else
				ndoeTemp:setVisible( false )
			end
		end
		local distanceX = specialHPPanelWidth/( shownNum + 1 )
		for i,v in ipairs( nodeListTemp ) do
			local posX = 0 + distanceX*i
			v:setPositionX( posX )
		end
	end
	self._specialHPInitEnd = true
end

function PlayerNode:setPlayerType(type)
	if type then
		self.actorType = tonumber(type)
	end
end

function PlayerNode:setType(type)
	self.type = type

	-- self:refreshManaVisible()
end

function PlayerNode:setFlip()
	if self:isHero() or self:isPartner() then
		if self.isLeft then
		--self.iconGroup:setFlippedX(true)
		else
			self.iconGroup:setFlippedX(true)
		end
	end
end

function PlayerNode:isHero()
    -- return self.type=="player"
    return self.type == Enums.UnitType.Player
end

function PlayerNode:isNpc()
    -- return self.type=="bnpc"
    return self.type == Enums.UnitType.Npc
end

function PlayerNode:isPartner()
	if self._isPartner then
		return self._isPartner
	end
	return false
end


function PlayerNode:setIsPartner(isPartner)
	self._isPartner = isPartner
end


function PlayerNode:setClassIcon(icon)
	if icon and self.mProfessionIcon then
		self.mProfessionIcon:setVisible(true)
		self.mProfessionIcon:loadTexture(icon)
	end
end

function PlayerNode:isOurTeam()
	local actorType = self.actorType
	if actorType == EBattleActorType_Self or actorType == EBattleActorType_Teammate then
		return true
	end
	return false
end

function PlayerNode:setSortWeight(weight)
	self._weight = self.bSelf and SELF_SORT_WEIGHT or weight
	if 0 == weight then
		self.playerNodeIndex = -1 -- 不显示
	else
		self.playerNodeIndex = self.lastPlayerNodeIndex
	end
end

function PlayerNode:getSortWeight()
	if not self._weight then
		local weight = 1
		if self.actorType == EBattleActorType_Self then
			weight = 10000 + weight
		elseif self.actorType == EBattleActorType_Boss then
			weight = 1000 + weight
		end
		self._weight = weight
	end
	return self.bSelf and SELF_SORT_WEIGHT or self._weight
end

function PlayerNode:setHpProgress(percent,hp)
	local isOldDead = self.signDead:isVisible()
	if hp > 0 then
		self.signDead:setVisible(false)
	else
		self.signDead:setVisible(true)
		self:setSkillBar(0)
	end

	if isOldDead ~= self:isDead() then
		self:refreshLockedAction()
	end

	--设置血条
	local bar = self:getHpBar()

    self.mHpPrecent = percent
    if bar then
        bar:setPercent(self.mHpPrecent)
    end
end

function PlayerNode:isDead()
	if self.signDead then
		return self.signDead:isVisible()
	end
	return false
end

function PlayerNode:hurtShake()
    local shakeNode = self.mRootNode

    local params = {
		duration = 0.1,--震动时间
		strengthX = 6,--x振幅
		strengthY = 6,--y振幅
		interval = 0,--间隔，多长时间刷新一次 单位秒,0表示每帧刷新
		intervalFactor = 1.0,
		dampingX = 0,--振幅衰减
		dampingXFactor = 1.0,
		dampingY = 0,
		dampingYFactor = 1.0,
	}


    if shakeNode then
    	shakeNode:stopAllActions()
        local actions = {}
        actions[#actions+1] = custom.Shaker:create(params.duration,params.strengthX,params.strengthY,params.interval, params.intervalFactor, params.dampingX, params.dampingXFactor, params.dampingY, params.dampingYFactor)
        actions[#actions+1] = cc.Place:create(cc.p(0,0))
        shakeNode:runAction(cc.Sequence:create(actions))
    end
end

function PlayerNode:updateBar(bar, targetPercent)
	if bar then
        local precent = tonumber(bar:getPercent())
        local targetPercent = tonumber(targetPercent)
        if targetPercent ~= precent then
            local step = 2

            local value = math.abs(targetPercent - precent)
            if value < step then
                step = value
            end

            local dir = 1
            if targetPercent < precent then
                dir = -1
            else
                dir = 1
            end
            precent = precent + dir*step
            bar:setPercent(precent)
        end
    end
end

function PlayerNode:updateFrame(dt)
	self:updateBar(self.hpBar, self.mHpPrecent)
end

function PlayerNode:showTips(data)
	if self.mTipsUI then
		self.mTipsUI:setVisible(true)
	else
		self.mTipsUI = cc.CSLoader:createNode(Res.BattlePlayerTips)
		local rootNode = self.mTipsUI:findChild("player")
		assert(rootNode)
		local buffNodeRoot = rootNode:findChild("05icon")
		local buffNodeContainer = buffNodeRoot:getInnerContainer()
	   	local buffOldSize = buffNodeContainer:getContentSize()
	   	buffNodeContainer:setContentSize(cc.size(buffOldSize.width,0))

		self:refreshTipsData(data)
		self:addChild(self.mTipsUI)

		local size = self:getContentSize()
	   	local posX,_ = self.mTipsUI:getParent():toWorldPosition(size.width/2.0,0)

	   	--保证不出屏幕
	   	local width = rootNode:getContentSize().width
	   	if posX - width/2.0 < 0 then
	   		posX = posX + width/2.0 - posX
	   	elseif posX + width/2.0 > display.width then
	   		posX = display.width - width/2.0
	   	end

	   	posX ,_ = self.mTipsUI:getParent():toLocalPosition(posX,0)
	   	self.mTipsUI:setPositionX(posX)

	   	-- local buffNodeRoot = rootNode:findChild("05icon")
	   	local buffHeight = buffNodeContainer:getContentSize().height

	   	local needAddHeight = buffHeight - buffOldSize.height


	   	-- local bgNode = rootNode:findChild("01bg")
	   	local bgSize = rootNode:getContentSize()
	   	rootNode:setContentSize(cc.size(bgSize.width,bgSize.height + needAddHeight))
	   	ccui.Helper:doLayout(rootNode)
	end

	self:playTipsUIAction()

end
function PlayerNode:isLeftSide()
	return self.isLeft
end

function PlayerNode:playTipsUIAction()
	if self.mTipsUI then
		if self.mTipsAction == nil then
			self.mTipsAction = cc.CSLoader:createTimeline(Res.BattlePlayerTips)
			assert(self.mTipsAction)
			if self.mTipsAction then
				self.mTipsUI:runAction(self.mTipsAction)
			end
		end
		if self.mTipsAction then
			self.mTipsAction:gotoFrameAndPlay(0,self.mTipsAction:getDuration(),false)
		end
	end
end

function PlayerNode:setIsSelf(bSelf)
	self.isSelf = bSelf
end

function PlayerNode:refreshTipsData(data)
	if self.mTipsUI then
		local rootNode = self.mTipsUI:findChild("player")
		assert(rootNode)

		local uiName = rootNode:findChild("02name")
		assert(uiName)
		uiName:setString(data.name)

		local uiLevel = rootNode:findChild("03Lv/03Num")
		assert(uiLevel)
		local levelNum = tonumber(data.level)
		if (not levelNum) or levelNum < 0 then
			levelNum = "??"
		end
		uiLevel:setString(levelNum)

		local uiClass = rootNode:findChild("04zhiye")
		assert(uiClass)
		if data.className then
			uiClass:setVisible(true)
			uiClass:setString(data.className)
		else
			uiClass:setVisible(false)
		end

		local buffNodeRoot = rootNode:findChild("05icon")
		assert(buffNodeRoot)
		buffNodeRoot:setTouchEnabled(false)
		local buffTemp = buffNodeRoot:getChildByName("buff_1")
		assert(buffTemp)
		buffTemp:retain()
		buffTemp:removeFromParent()

		local function createBuffIcon(iconPath)
			if iconPath then
				local buffIcon = buffTemp:clone()
				buffIcon:loadTexture(iconPath)
				return buffIcon
			end
			return nil
		end

		buffNodeRoot:removeAllChildren()
		local views = {}
		-- for i=1,#data.buffList do
		for k,buffData in pairs(data.buffList) do
		    if buffData then
		    	local view = createBuffIcon(buffData.icon)
		    	if view then
		    		table.insert(views,view)
		    	end
		    end
		end
		local count = #views

		local cellCount = 5
		if count > 0 then
	        display.ScrollViewFill(buffNodeRoot, views,
	        {
	                --自动间距
	                autoGap = false,
	                --宽间距
	                widthGap = 0,
	                --高间距
	                heightGap = 0,
	                --自动行列
	                autoTable = false,
	                --行数目
	                -- rowCount = 4,
	                --列数目
	                cellCount = cellCount,
	                --填充项大小
	                itemSize = views[1]:getContentSize(),
	                --容器大小根据item多少决定
	                autoSize = true,
	            })

	        -- buffNodeRoot:scrollToBottom(0.1,true)
	    end

	    buffTemp:release()
	end
end

function PlayerNode:hideTips()
	if self.mTipsUI then
		self.mTipsUI:removeFromParent()
		self.mTipsUI = nil
		self.mTipsAction = nil
	end
end

function PlayerNode:prepareWarningNode()
    if self._warningNode == nil then
        self._warningNode = display.newArmature({path=Res.ActorWarningEffect.dir,armatureName=Res.ActorWarningEffect.name,animationName="",skeletonName=Res.ActorWarningEffect.name})
        self:addChild(self._warningNode)
		self._warningNode:getAnimation():play()

		self._warningNode:setPositionX(self.mRootNode:getPositionX())
    end
end

function PlayerNode:setWarning(isVisible, time)
	self:prepareWarningNode()
	if self._warningNode then
		self._warningNode:setVisible(isVisible)
		-- if isVisible then
        --     self.warningNodeNum:setString(time)
        -- end
	end
end

function PlayerNode:setTeamMarkId(markId)

end

function PlayerNode:setIndex(playerNodeIndex)
	self.playerNodeIndex = playerNodeIndex
	self.lastPlayerNodeIndex = playerNodeIndex
	self:setLocalZOrder(playerNodeIndex)
end

function PlayerNode:getIndex()
	return self.playerNodeIndex or 1
end

function PlayerNode:runLockedAction(scale, opacity)
	self.mRootNode:stopActionByTag(Enums.CommonActionTag.BattlePlayerNodeLocked)
	local action1 = cc.ScaleTo:create(0.1, scale)
	local action2 = cc.FadeTo:create(0.1, opacity)

	local action = cc.Spawn:create(action1, action2)
	action:setTag(Enums.CommonActionTag.BattlePlayerNodeLocked)
	self.mRootNode:runAction(action)
	local action3 = cc.FadeTo:create(0.2, opacity)
	self.mIcon:runAction(action3)
end

function PlayerNode:setCurrentPlayerTargetFlag(isCurrentPlayerTarget)
	self.isCurrentPlayerTarget = isCurrentPlayerTarget
	self.mTipsBtn:setBright(not self.isCurrentPlayerTarget)
	self:refreshLockedAction()
end

function PlayerNode:refreshLockedAction()
	if self.isCurrentPlayerTarget then
		-- self.mRootNode:setScale(self.initScale*1.2)
		self:runLockedAction(self.initScale*1.2, 255)
	else
		if self:isDead() then
			self:runLockedAction(self.initScale, 255*0.2)
		else
			self:runLockedAction(self.initScale, self.initOpacity)
	end
	end
end

-- 隐藏血条显示
function PlayerNode:shouldHideAllHpUI(flag)
	if self._hpVisibleFlag == flag then return end
	self._hpVisibleFlag = flag

	-- 隐藏血条时特效的显示
	if cc.isDead(self.hpHideEffectNode) then
		local params =
		{
			path = Res.HideHpEffect_2.dir,
			armatureName = Res.HideHpEffect_2.name,
			animationName = "",
			skeletonName = Res.HideHpEffect_2.name
		}
		local Armature = app:getClass("Armature")
		self.hpHideEffectNode = Armature.create(params)
		self.hpBar:getParent():addChild(self.hpHideEffectNode)
		self.hpHideEffectNode:setPosition(self.hpBar:getPosition())
		self.hpHideEffectNode:setScale(0.45)
	end
	self.hpHideEffectNode:setVisible(flag)
	if flag then
		self.hpHideEffectNode:play("effcreat", 1,
			function()
				self.hpHideEffectNode:play("effloop", 1,
					function()
						self.hpHideEffectNode:play("effdead", 1)
					end)
			end)
	end
end

function PlayerNode:clearHideEffect()
	if not cc.isDead(self.hpHideEffectNode) then
		self.hpHideEffectNode:removeFromParent()
		self.hpHideEffectNode = nil
	end
end

return PlayerNode
